home *** CD-ROM | disk | FTP | other *** search
/ Apple Color Graphics Sampler / Apple Color Graphics Sampler.iso / English / Screen Savers / Dark Side of the Mac / FaderShell / Blackout.c next >
Encoding:
Text File  |  1998-11-17  |  17.0 KB  |  665 lines  |  [TEXT/MPS ]

  1. /*
  2.  
  3.     Blackout.c - A simple screen fader that runs as a MultiFinder
  4.     application.  Is typically launched by Lunarmobiscuit's
  5.     Darkness MultiFinder screen saver program.
  6.     
  7.     copyright © 1989 by Tom Dowdy
  8.     All rights reserved
  9.     
  10.     Modifications
  11.         Aug    5 1989        TED        basic fade working as standalone code
  12.         Nov 30 1989        TED        file converted to a standalone application
  13.         
  14.     Assumptions:
  15.         MultiFinder is present.
  16.         
  17.     Slightly questionables:
  18.         Uses lowMem mBarHeight for setting menu bar height to 0.
  19.         Modifies a window's visRgn to include the menu bar.
  20.         
  21.     
  22. */
  23.  
  24. // Standard MacIncludes - you might wish to use a dump file for this
  25. #include <Limits.h>
  26. #include <Types.h>
  27. #include <Resources.h>
  28. #include <QuickDraw.h>
  29. #include <Fonts.h>
  30. #include <Events.h>
  31. #include <Windows.h>
  32. #include <Menus.h>
  33. #include <TextEdit.h>
  34. #include <Dialogs.h>
  35. #include <Desk.h>
  36. #include <ToolUtils.h>
  37. #include <Memory.h>
  38. #include <SegLoad.h>
  39. #include <Devices.h>
  40. #include <Files.h>
  41. #include <OSUtils.h>
  42. #include <OSEvents.h>
  43. #include <Traps.h>    
  44. #include <SysEqu.h>
  45. #include <Script.h>
  46. #include <Picker.h>
  47. #include <FixMath.h>
  48. #include <Packages.h>
  49. #include <Math.h>
  50. #include <Palette.h>
  51. #include <QDOffscreen.h>
  52. #include <DeskBus.h>
  53. #include <StdLib.h>
  54. #include <StdArg.h>
  55. #include <Strings.h>
  56. #include <StdIO.h>
  57.  
  58. // Defines to let this include work okay
  59. #define INMAINBLACKOUT
  60. typedef Handle BlackoutHandle;
  61.  
  62. #include "Blackout.h"
  63.  
  64.  
  65. /* ------------------------------------------------------------------------------------    */
  66. /*    INTERNAL ROUTINES - Shouldn't need to be changed by Blackout authors.                */
  67. /* ------------------------------------------------------------------------------------    */
  68. #define mBarHeight    (short *)0x0BAA        // Low mem global for menu bar
  69. #define    kOSEvent                app4Evt    // event used by MultiFinder
  70. #define    kSuspendResumeMessage    1        // high byte of suspend/resume event message
  71. #define    kResumeMask                1        // bit of message field for resume vs. suspend
  72.  
  73. #define TopLeft(aRect)    (* (Point *) &(aRect).top)
  74. #define BotRight(aRect)    (* (Point *) &(aRect).bottom)
  75.  
  76.  
  77. /* This routine is part of the MPW runtime library. This external
  78.    reference to it is done so that we can unload its segment, %A5Init. */
  79. extern void _DataInit();
  80.  
  81. SysEnvRec    theEnvirons;
  82. Boolean        gHas32BitQD;
  83.  
  84. /* ------------------------------------------------------------------------------------    */
  85. #pragma segment Main
  86.  
  87. void PlaceRectOnScreen(
  88.     short width,        // width of rect, can be 0
  89.     short height,        // height of rect, can be 0
  90.     Rect * placedRect,    // Placed rect is returned here
  91.     Rect * margins,        // margins around screen, can be nil
  92.     Rect * screenBound)    // placed screen bounds returned here, can be nil
  93. {
  94.     Rect        screenRect;
  95.     short        deviceCount;
  96.     GDHandle    theDevice;
  97.     
  98.     if (theEnvirons.hasColorQD)
  99.         {
  100.         // First, count the GDevices
  101.         deviceCount = 0;
  102.         theDevice = GetDeviceList();
  103.         while (theDevice != nil)
  104.             {
  105.             if ( (TestDeviceAttribute(theDevice, screenDevice)) &&
  106.                 (TestDeviceAttribute(theDevice, screenActive)) )
  107.                 deviceCount++;
  108.             theDevice = GetNextDevice(theDevice);
  109.             }
  110.             
  111.         // Then pick one at random
  112.         deviceCount = Rnd(deviceCount)+1;
  113.         
  114.         // Fetch that GDevice
  115.         theDevice = GetDeviceList();
  116.         while (deviceCount != 0)
  117.             {
  118.             if ( (TestDeviceAttribute(theDevice, screenDevice)) &&
  119.                 (TestDeviceAttribute(theDevice, screenActive)) )
  120.                 {
  121.                 deviceCount--;
  122.                 if (deviceCount == 0)
  123.                     screenRect = (**theDevice).gdRect;
  124.                 }
  125.             theDevice = GetNextDevice(theDevice);
  126.             }
  127.         
  128.         }
  129.     else
  130.         screenRect = (**GetGrayRgn()).rgnBBox;
  131.         
  132.     // Localize the points
  133.     GlobalToLocal(&TopLeft(screenRect));
  134.     GlobalToLocal(&BotRight(screenRect));
  135.     
  136.     if (margins != nil)
  137.         {
  138.         screenRect.top += margins->top;
  139.         screenRect.left += margins->left;
  140.         screenRect.bottom -= margins->bottom;
  141.         screenRect.right -= margins->right;
  142.         }
  143.     if (screenBound != nil)
  144.         *screenBound = screenRect;
  145.         
  146.     screenRect.right -= width;
  147.     screenRect.bottom -= height;
  148.     
  149.     placedRect->top = screenRect.top + Rnd(screenRect.bottom - screenRect.top);
  150.     placedRect->left = screenRect.left + Rnd(screenRect.right - screenRect.left);
  151.     placedRect->bottom = placedRect->top + height;
  152.     placedRect->right = placedRect->left + width;
  153.     
  154. } // PlaceRectOnScreen
  155.  
  156. /* ------------------------------------------------------------------------------------    */
  157. #pragma segment Main
  158.  
  159. short    Rnd(long max)
  160. {
  161.     long    value;
  162.     
  163.     value = max * Random();
  164.     if (value < 0)
  165.         value = -value;
  166.     value /= 32767;
  167.     if (value == max)
  168.         value--;
  169.     return(value);
  170.     
  171. } // Rnd
  172.  
  173. /* ------------------------------------------------------------------------------------    */
  174. #pragma segment Main
  175.  
  176. void AddMenuBarIntoVisRgn(WindowPtr theWindow, short oldMenuBarHeight)
  177. {
  178.     RgnHandle    mBarRgn;
  179.     Rect        mBarRect;
  180.         
  181.     /*    At this point, our new window doesn't include the menu bar,
  182.         so make a region out of the menu bar, and add it onto
  183.         the window's visRgn */
  184.     mBarRgn = NewRgn();
  185.     if (mBarRgn != nil)
  186.         {
  187.         /* Calculate the rect of the menu bar */
  188.         mBarRect = qd.screenBits.bounds;
  189.         mBarRect.bottom = mBarRect.top + oldMenuBarHeight;
  190.         
  191.         /* ScreenBit is in global, vis regions are local */
  192.         GlobalToLocal(&TopLeft(mBarRect));
  193.         GlobalToLocal(&BotRight(mBarRect));
  194.         
  195.         /* Make a region out of the menu bar */
  196.         RectRgn(mBarRgn, &mBarRect);
  197.         
  198.         /* Tack this region onto the visRgn */
  199.         UnionRgn(theWindow->visRgn, mBarRgn, theWindow->visRgn);
  200.                 
  201.         /* Get rid of our temp region */
  202.         DisposeRgn(mBarRgn);
  203.         } // mBarRgn != nil
  204.         
  205. } // AddMenuBarIntoVisRgn
  206.  
  207. /* ------------------------------------------------------------------------------------    */
  208. /*    OFFSCREEN PIXMAP UTILTIES                                                            */
  209. /* ------------------------------------------------------------------------------------    */
  210. void    MyDisposeGWorld (GWorldPtr offscreenGWorld);
  211.  
  212. #pragma segment Initialize
  213.  
  214. void MyNewGWorld(GWorldPtr *offscreenGWorld,short PixelDepth,Rect *boundsRect,
  215.     CTabHandle cTable,GDHandle aGDevice,GWorldFlags flags)
  216. {
  217.     long        offRowBytes, sizeOfOff;
  218.     Ptr            myBits;
  219.     GrafPtr        curPort;
  220.     GDHandle    oldDevice;
  221.     CTabHandle    ourCMHandle;
  222.     short        i;
  223.     
  224.     GetPort(&curPort);
  225.             
  226.     gHas32BitQD = false;        
  227.     if (theEnvirons.hasColorQD)
  228.         {
  229.         if (NGetTrapAddress (0xAB03, ToolTrap) != NGetTrapAddress (0xA89F, ToolTrap))
  230.             gHas32BitQD = true;
  231.         }
  232.         
  233.     if (gHas32BitQD)
  234.         {
  235.         if (NewGWorld (offscreenGWorld, PixelDepth, boundsRect, cTable, nil, flags) != noErr)
  236.             *offscreenGWorld = nil;
  237.         return;
  238.         }
  239.     else
  240.         {
  241.         *offscreenGWorld = (GWorldPtr) NewPtr(sizeof(CGrafPort));
  242.         if (*offscreenGWorld == nil)
  243.             return;
  244.  
  245.         if (theEnvirons.hasColorQD)
  246.             {
  247.             oldDevice = GetGDevice();
  248.             if (aGDevice != nil)
  249.                 SetGDevice(aGDevice);
  250.             OpenCPort((CGrafPtr) *offscreenGWorld);
  251.             }
  252.         else
  253.             {
  254.             OpenPort((GrafPtr) *offscreenGWorld);
  255.             }
  256.             
  257.         offRowBytes = ((((PixelDepth * (RectWidth(boundsRect))) + 15)) / 16) * 2;
  258.         sizeOfOff = ((long) RectHeight(boundsRect)) * offRowBytes;
  259.         myBits = NewPtr(sizeOfOff);
  260.         
  261.         if (myBits == nil)
  262.             {
  263.             MyDisposeGWorld(*offscreenGWorld);
  264.             *offscreenGWorld = nil;
  265.             goto cleanUp;
  266.             }
  267.             
  268.         if (theEnvirons.hasColorQD)
  269.             {
  270.             (** ((CGrafPtr) *offscreenGWorld)->portPixMap).baseAddr = myBits;
  271.             (** ((CGrafPtr) *offscreenGWorld)->portPixMap).rowBytes = offRowBytes + 0x8000;
  272.             (** ((CGrafPtr) *offscreenGWorld)->portPixMap).bounds = *boundsRect;
  273.             (** ((CGrafPtr) *offscreenGWorld)->portPixMap).pmTable = nil;
  274.             
  275.             // and clone that color table!
  276.             ourCMHandle = (**(**aGDevice).gdPMap).pmTable;
  277.             if (HandToHand( &(Handle) ourCMHandle) == noErr)
  278.                 {
  279.                 for (i = 0; i <= (**ourCMHandle).ctSize; ++i)
  280.                     (**ourCMHandle).ctTable[i].value = i;
  281.                 (**ourCMHandle).ctFlags &= 0x7fff;
  282.                 offRowBytes = GetCTSeed();
  283.                 (**ourCMHandle).ctSeed = offRowBytes;
  284.                 (** ((CGrafPtr) *offscreenGWorld)->portPixMap).pmTable = ourCMHandle;
  285.                 }
  286.             else
  287.                 {
  288.                 MyDisposeGWorld(*offscreenGWorld);
  289.                 *offscreenGWorld = nil;
  290.                 goto cleanUp;
  291.                 }
  292.                 
  293.             }
  294.         else
  295.             {
  296.             ((GrafPtr) *offscreenGWorld)->portBits.baseAddr = myBits;
  297.             ((GrafPtr) *offscreenGWorld)->portBits.rowBytes = offRowBytes;
  298.             ((GrafPtr) *offscreenGWorld)->portBits.bounds = *boundsRect;
  299.             }
  300.         }
  301.         
  302. cleanUp:        
  303.     SetPort(curPort);
  304.     if (theEnvirons.hasColorQD)
  305.         SetGDevice(oldDevice);
  306.         
  307.     return;
  308. }
  309.  
  310. /* ------------------------------------------------------------------------------------    */
  311. #pragma segment Terminate
  312.  
  313. void    MyDisposeGWorld (GWorldPtr offscreenGWorld)
  314. {
  315.     if (offscreenGWorld != nil)
  316.         if (gHas32BitQD)
  317.             {
  318.             DisposeGWorld(offscreenGWorld);
  319.             }
  320.         else
  321.             {
  322.             if (theEnvirons.hasColorQD)
  323.                 {
  324.                 CloseCPort((CGrafPtr) offscreenGWorld);
  325.                 if ( (** ((CGrafPtr) offscreenGWorld)->portPixMap).pmTable != nil) 
  326.                     DisposHandle((Handle) (** ((CGrafPtr) offscreenGWorld)->portPixMap).pmTable);
  327.                 }
  328.             else
  329.                 ClosePort((GrafPtr) offscreenGWorld);
  330.                 
  331.             if ((Ptr) ((GrafPtr) offscreenGWorld)->portBits.baseAddr != nil)
  332.                 DisposPtr((Ptr) ((GrafPtr) offscreenGWorld)->portBits.baseAddr);
  333.             DisposPtr((Ptr) offscreenGWorld);
  334.             }
  335. }
  336.  
  337. /* ------------------------------------------------------------------------------------    */
  338. #pragma segment Main
  339.  
  340. void MySetGWorld(GWorldPtr offscreenGWorld)
  341. {
  342.     if (offscreenGWorld != nil)
  343.         {
  344.         if (gHas32BitQD)
  345.             SetGWorld (offscreenGWorld, nil);
  346.         else
  347.             SetPort((GrafPtr) offscreenGWorld);
  348.         }
  349. }
  350. /* ------------------------------------------------------------------------------------    */
  351. #pragma segment Main
  352.  
  353. void MyLockPixels(GWorldPtr offscreenGWorld)
  354. {
  355.     if (offscreenGWorld != nil)
  356.         if (gHas32BitQD)
  357.             LockPixels (offscreenGWorld->portPixMap);
  358. }
  359. /* ------------------------------------------------------------------------------------    */
  360. #pragma segment Main
  361.  
  362. void MyUnlockPixels(GWorldPtr offscreenGWorld)
  363. {
  364.     if (offscreenGWorld != nil)
  365.         if (gHas32BitQD)
  366.             UnlockPixels (offscreenGWorld->portPixMap);
  367. }
  368.  
  369. /* ------------------------------------------------------------------------------------    */
  370. /* ------------------------------------------------------------------------------------    */
  371. #pragma segment Main
  372.  
  373. void        AppleShareDialogs(Boolean turnOn)
  374. {
  375. #define    AFPSetAlertState    247
  376. #define    DontShowAlerts        1
  377. #define    DoShowAlerts        0
  378. #define    AFPTransRefNum        -42
  379.  
  380.     short    csParam[11];                /*operation-defined parameters*/
  381.     short    anErr;
  382.     
  383.     if (turnOn)
  384.         csParam[1] = DoShowAlerts;
  385.     else
  386.         csParam[0] = DontShowAlerts;
  387.  
  388.     (void) Control(AFPTransRefNum,AFPSetAlertState,(Ptr)csParam);
  389.         
  390. } // AppleShareDialogs
  391.  
  392. /* ------------------------------------------------------------------------------------    */
  393. #pragma segment Initialize
  394.  
  395. WindowPtr    CreateBigWindow(short oldMenuBarHeight)
  396. {
  397.     Rect        theRect;
  398.     RgnHandle    theGrayRgn;
  399.     WindowPtr    theWindow;
  400.     
  401.     /* Get the full size of the desktop */
  402.     theGrayRgn = GetGrayRgn();
  403.     
  404.     /* Get the bounding box for the gray region */
  405.     theRect = (**theGrayRgn).rgnBBox;
  406.     
  407.     /* Add on the screenbits.bounds, which will include the menu bar */
  408.     UnionRect(&theRect, &qd.screenBits.bounds, &theRect);
  409.             
  410.     /* Make a big window of this size */
  411.     if (theEnvirons.hasColorQD)
  412.         theWindow = NewCWindow(nil, &theRect, "\p", true,
  413.             plainDBox, (WindowPtr) -1,  false, 0);
  414.     else
  415.         theWindow = NewWindow(nil, &theRect, "\p", true,
  416.             plainDBox, (WindowPtr) -1,  false, 0);
  417.         
  418.     /* If got the window okay, time to modify the visRgn */
  419.     if (theWindow != nil)
  420.         {
  421.         /* Set port to it */
  422.         SetPort(theWindow);
  423.             
  424.         AddMenuBarIntoVisRgn(theWindow, oldMenuBarHeight);
  425.         } // theWindow != nil
  426.         
  427.     return(theWindow);
  428.  
  429. } // CreateBigWindow
  430.  
  431. /* ------------------------------------------------------------------------------------    */
  432. /* PRIVATE GLOBAL AREA                                                                    */
  433. /* ------------------------------------------------------------------------------------    */
  434.     // Misc variables
  435.     short        gOldMenuBarHeight;        // For restoring the old menu bar
  436.     short        gCount;                    // Misc loop variable
  437.     
  438.     // State information for the Blackout effect that is in use
  439.     WindowPtr    gBlackoutWindow;
  440.     Handle        gTheBlackout;
  441.     long        gMinSleepTime;
  442.     long        gMaxSleepTime;
  443.     long        gSleepTime;
  444.     Boolean        gHaveBlackout;
  445.     
  446.     // Variables to keep track of events and when to terminate the application
  447.     Point        gOldMouse;
  448.     short        gOldModifiers;
  449.     long        gOldTime;
  450.     Boolean        gContinueRunning;
  451.     EventRecord    gTheEvent;
  452. /* ------------------------------------------------------------------------------------    */
  453. #pragma segment Initialize
  454.  
  455. void Initialize()
  456. {
  457.     unsigned long    aSeed;
  458.  
  459.     UnloadSeg((Ptr) _DataInit);        /* note that _DataInit must not be in Main! */
  460.  
  461.     MaxApplZone();                    /* expand the heap so code segments load at the top */    
  462.     
  463.     /* Initialize the toolbox */
  464.     InitGraf((Ptr) &qd.thePort);
  465.     InitFonts();
  466.     InitWindows();
  467.     InitMenus();
  468.     TEInit();
  469.     InitDialogs(nil);
  470.     InitCursor();
  471.     
  472.     // Seed the random number generator
  473.     GetDateTime(&aSeed);
  474.     qd.randSeed = aSeed;
  475.  
  476.     /*    We need a menu or MultiFinder will drop into Macsbug.  In addition, it
  477.         should be a File:Quit menu so that MultiFinder can shut us down via
  478.         a puppet string. */
  479.     InsertMenu(GetMenu(1), 0);
  480.     DrawMenuBar();
  481.     
  482.     /* Get our application to the front */
  483.     for (gCount = 1; gCount <= 4; ++gCount)
  484.         EventAvail(everyEvent, &gTheEvent);
  485.         
  486.     /* Turn off AppleShare dialogs */
  487.     AppleShareDialogs(false);
  488.     
  489.     /* Save away the old menu bar height and set it to zero */
  490.     gOldMenuBarHeight = GetMBarHeight();
  491.     *mBarHeight = 0;
  492.     
  493.     /* Find out if we have color QuickDraw */
  494.     SysEnvirons(1, &theEnvirons);
  495.  
  496.     gMinSleepTime = 0;
  497.     gMaxSleepTime = 1;
  498.     gSleepTime = 1;
  499.     gTheBlackout = PreflightBlackout(&gMinSleepTime, &gMaxSleepTime);
  500.  
  501.     gBlackoutWindow = CreateBigWindow(gOldMenuBarHeight);
  502.     if (gBlackoutWindow != nil)
  503.         {
  504.         /* Get the initial mouse position in globals */
  505.         GetMouse(&gOldMouse);
  506.         LocalToGlobal(&gOldMouse);
  507.         
  508.         /* Get the initial modifier keys */
  509.         gOldModifiers = gTheEvent.modifiers & (cmdKey + shiftKey + optionKey + controlKey + alphaLock);
  510.         
  511.         /* Hide the cursor from people */
  512.         HideCursor();
  513.         
  514.         gOldTime = TickCount();
  515.         
  516.         gHaveBlackout = false;
  517.         gContinueRunning = true;
  518.         }
  519.             
  520. } // Initialize
  521.  
  522. /* ------------------------------------------------------------------------------------    */
  523. #pragma segment Main
  524.  
  525. main()
  526. {
  527.     long    timer;
  528.     
  529.     Initialize();
  530.     UnloadSeg((Ptr) Initialize);
  531.     
  532.     if (gBlackoutWindow != nil)
  533.         {
  534.         
  535.         do
  536.             {
  537.             timer = -TickCount();
  538.             WaitNextEvent(everyEvent, &gTheEvent, gSleepTime, nil);
  539.             timer += TickCount();
  540.             
  541.             if (timer > gSleepTime)
  542.                 gSleepTime = timer;
  543.             else
  544.                 gSleepTime--;
  545.                 
  546.             if (gSleepTime < gMinSleepTime)
  547.                 gSleepTime = gMinSleepTime;
  548.             else
  549.                 if (gSleepTime > gMaxSleepTime)
  550.                     gSleepTime = gMaxSleepTime;
  551.                     
  552.             if (! BlackoutEvent(&gTheEvent))
  553.                 {
  554.                 /* Abort if mouse moved */
  555.                 if ((gTheEvent.where.h != gOldMouse.h) ||
  556.                     (gTheEvent.where.v != gOldMouse.v))
  557.                     gContinueRunning = false;
  558.                     
  559.                     
  560.                 /* Abort if modifiers are down */
  561.                 if ((gTheEvent.modifiers & (cmdKey + shiftKey + optionKey + controlKey + alphaLock)) != gOldModifiers)
  562.                     {
  563.                     gOldModifiers = 0;
  564.                     
  565.                     if (gTheEvent.modifiers & (cmdKey + shiftKey + optionKey + controlKey + alphaLock)) 
  566.                         gContinueRunning = false;
  567.                     }
  568.                                 
  569.                 switch (gTheEvent.what)
  570.                     {
  571.                     /* Abort if user event */
  572.                     case keyDown:
  573.                     case autoKey:
  574.                     case mouseDown:
  575.                     case mouseUp:
  576.                     case diskEvt:
  577.                         gContinueRunning = false;
  578.                         break;
  579.                         
  580.                     /* If update event, clean out the update */
  581.                     case updateEvt:
  582.                         BeginUpdate((WindowPtr) gTheEvent.message);
  583.                         EndUpdate((WindowPtr) gTheEvent.message);
  584.                         break;
  585.                         
  586.                     /* Activate means window has come to front */
  587.                     case activateEvt:
  588.                         if (!gHaveBlackout)
  589.                             {
  590.                             /* Make sure Menu bar is part of the window */
  591.                             AddMenuBarIntoVisRgn(gBlackoutWindow, gOldMenuBarHeight);
  592.  
  593.                             /* restore previous menu bar height, for notification manager */
  594.                             *mBarHeight = gOldMenuBarHeight;
  595.                             
  596.                             gHaveBlackout = true;
  597.                             
  598.                             /* Start up the screen saver */
  599.                             gContinueRunning = InitBlackout(gTheBlackout, gBlackoutWindow);
  600.     
  601.                             /* Get the initial mouse position in globals in case the init causes a
  602.                                 move of the mouse for the OK button of a dialog or something. */
  603.                             GetMouse(&gOldMouse);
  604.                             LocalToGlobal(&gOldMouse);
  605.                             
  606.                             /* Make the mouse invisible until moved */
  607.                             ObscureCursor();
  608.                             }
  609.                         break;
  610.                         
  611.                     /* If a suspend event, Abort */
  612.                     case kOSEvent:
  613.                         switch (gTheEvent.message >> 24) {        /* high byte of message */
  614.                             case kSuspendResumeMessage:
  615.                                 if ((gTheEvent.message & kResumeMask) == 0)
  616.                                     gContinueRunning = false;
  617.                                 break;
  618.                         }
  619.                         break;
  620.                         
  621.                     default:
  622.                         break;
  623.                         
  624.                     } // switch(gTheEvent.what)
  625.                     
  626.                 } // ! BlackoutEvent
  627.                 
  628.             
  629.             if ((gHaveBlackout) && (gContinueRunning))
  630.                 {
  631.                 /* Give the Blackout some time */
  632.                 BlackoutIdle(gBlackoutWindow, gTheBlackout);
  633.                 
  634.                 /* Make sure the cursor is hidden every 10 seconds, if visible (MPW is fond of doing this to us) */
  635.                 if (gOldTime <= gTheEvent.when)
  636.                     {
  637.                     ObscureCursor();
  638.                     gOldTime = TickCount() + 600;
  639.                     }
  640.                 }
  641.  
  642.             UnloadSeg((Ptr) Initialize);
  643.                                 
  644.             } while (gContinueRunning);
  645.         
  646.         if (gHaveBlackout)
  647.             {
  648.             /* Close down the screen saver */
  649.             DisposeBlackout(gTheBlackout);
  650.             }
  651.             
  652.         /* Get rid of our window */
  653.         DisposeWindow(gBlackoutWindow);
  654.  
  655.         /* Show the cursor to the nice people */
  656.         ShowCursor();
  657.         } 
  658.         
  659.     /* Restore previous menu bar height */
  660.     DrawMenuBar();
  661.  
  662.     /* Turn on AppleShare dialogs */
  663.     AppleShareDialogs(true);
  664.     
  665. } // main